package com.elysia.visionmanagerspringboot.untils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.*;
import com.elysia.visionmanagerspringboot.enumeration.ResourceTypeEnum;
import com.elysia.visionmanagerspringboot.properties.AliyunOssProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

@Component
@RequiredArgsConstructor
@Slf4j
public class AliyunOssUtil {
    private final OSS ossClient;
    private final AliyunOssProperties aliyunOssProperties;

    /**
     * 上传文件到指定Bucket的指定文件夹
     *
     * @param file           要上传的文件
     * @param resourceType   文件类型
     * @return 文件在OSS中的完整路径
     * @throws IOException 如果文件处理过程中发生错误
     */
    public String uploadFile(MultipartFile file, ResourceTypeEnum resourceType) throws IOException {
        // 验证文件是否为空
        if (file.isEmpty()) {
            throw new IllegalArgumentException("上传的文件不能为空");
        }
        // 获取Bucket名称
        String bucketName = aliyunOssProperties.getBucketName();
        // 获取对应文件夹路径
        String folderPath = resourceType.getValue() + "/";
        if (resourceType == ResourceTypeEnum.VIDEO)
            folderPath = folderPath + "resource/";
        // 生成唯一文件名，避免重复
        String originalFilename = file.getOriginalFilename();
        String fileExtension = "";
        if (originalFilename != null && originalFilename.contains("."))
            fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = UUID.randomUUID() + fileExtension;
        // 构建完整的OSS文件路径
        String key = folderPath + fileName;
        // 获取文件输入流
        try (InputStream inputStream = file.getInputStream()) {
            // 创建上传请求
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream);
            // 设置文件元数据
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(file.getContentType());
            putObjectRequest.setMetadata(metadata);
            // 执行上传
            ossClient.putObject(putObjectRequest);
        }
        return key;
    }

    /**
     * 获取文件的临时访问URL
     *
     * @param objectKey 文件在OSS中的完整路径（包含文件夹）
     * @param expireSeconds URL的过期时间（秒）
     * @return 可直接访问的文件URL
     */
    public String getFileUrl(String objectKey, int expireSeconds) {
        if (objectKey == null || objectKey.isEmpty())
            throw new IllegalArgumentException("文件路径不能为空");
        if (expireSeconds <= 0)
            throw new IllegalArgumentException("过期时间必须大于0");
        String bucketName = aliyunOssProperties.getBucketName();
        // 检查文件是否存在
        if (!ossClient.doesObjectExist(bucketName, objectKey))
            throw new IllegalArgumentException("文件不存在，可能是正在生成: " + objectKey);
        // 计算过期时间
        Date expiration = new Date(System.currentTimeMillis() + expireSeconds * 1000L);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, objectKey, expiration);
        return url.toString();
    }

    /**
     * 根据文件在OSS中的完整路径删除资源
     *
     * @param objectKey 文件在OSS中的完整路径（包含文件夹）
     */
    public void deleteFile(String objectKey) {
        if (objectKey == null || objectKey.isEmpty()) {
            throw new IllegalArgumentException("文件路径不能为空");
        }
        String bucketName = aliyunOssProperties.getBucketName();
        // 检查文件是否存在
        if (!ossClient.doesObjectExist(bucketName, objectKey)) {
            throw new IllegalArgumentException("文件不存在: " + objectKey);
        }
        // 执行删除操作
        ossClient.deleteObject(bucketName, objectKey);
    }
}
